<?php
namespace Modules\User\Http\Controllers\Client\V1;

use Illuminate\Http\Request;
use Illuminate\Routing\Controller;

use Modules\User\Entities\User;

use Modules\Core\Helpers\HttpClient;

use Validator;
use ThrowException;
use Auth;
use DB;
use Cache;
use Miniapp;
use ByteDance;
use Setting;
use SMS;

class LoginController extends Controller
{
    // 获取手机号
    public function phoneCode(Request $req)
    {
        $rule = [
            'phone' => ['required']
        ];
        Validator::make($req->all(), $rule)->fails() && ThrowException::BadRequest();

        // 手机号简单验证
        if ($req->input('phone')) {
            if (strlen($req->phone) !== 11) {
                ThrowException::Conflict('手机号格式不正确~');
            }
        }

        SMS::sendCode($req->phone, 'login');

        return [];
    }

    // 微信小程序登陆
    public function loginWithWechat(Request $req)
    {
        $rule = [
            // 'iv' => ['required'],
            // 'encrypt_data' => ['required'],
            // 'code' => ['required'],
        ];
        Validator::make($req->all(), $rule)->fails() && ThrowException::BadRequest();

        // 如果有data_uuid，则直接从缓存中读取而不使用授权信息读取
        if ($req->input('data_uuid')) {
            $data = Cache::get('login_data_' . $req->data_uuid);

            // 微信授权的同时有手机号授权
            if ($req->input('phone_iv')) {
                $tempData = Miniapp::get()->getUserInfo($req->phone_code, $req->phone_iv, $req->phone_encrypt_data);
                $phoneNumber = @$tempData['purePhoneNumber'] ?: ThrowException::Conflict('获取手机号失败');
                $data['phone'] = $phoneNumber;
            }
        }
        else {
            $data = Miniapp::get()->getUserInfo($req->code, $req->iv, $req->encrypt_data);
        }

        // 手机号简单验证
        if ($req->input('phone')) {
            if (strlen($req->phone) !== 11) {
                ThrowException::Conflict('手机号格式不正确~');
            }
        }

        // 有手机号则验证手机号
        if ($req->input('phone')) {
            SMS::verifyCode($req->phone, $req->phone_code, 'login') || ThrowException::Conflict('验证码不正确');
            $data['phone'] = $req->phone;
        }
        
        DB::beginTransaction();

        $openidType = 'miniapp';
        
        list($user, $isCreated) = User::findOrCreateByWechat($data, Auth::clientName(), $openidType);

        // 没有找到用户并且没有创建新用户
        if (!$user) {

            $dataUuid = uniqid();
            Cache::put('login_data_' . $dataUuid, $data, 300);

            return [
                'data_uuid' => $dataUuid,
                'is_need_phone_number' => 1
            ];
        } 

        // 绑定邀请人
        if ($req->input('inviter') && $isCreated) {
            $inviter = User::getEntity([
                'uuid' => $req->inviter
            ], false);

            $user->bindInviter($inviter, $req);
        }

        DB::commit();

        $token = Auth::generateToken($user);

        return [
            'token' => $token,
            'is_first_login' => $isCreated ? 1 : 0
        ];
    }


    // app微信授权登陆
    public function loginWithAppByWechat(Request $req)
    {
        $rule = [
            // 'openid' => ['required'],
            // 'access_token' => ['required'],
            // 'code' => ['required'],
        ];
        Validator::make($req->all(), $rule)->fails() && ThrowException::BadRequest();

        // 手机号简单验证
        if ($req->input('phone')) {
            if (strlen($req->phone) !== 11) {
                ThrowException::Conflict('手机号格式不正确~');
            }
        }

        $phone = $req->input('phone');
        $phoneCode = $req->input('phone_code');

        // 如果有data_uuid，则直接从缓存中读取而不使用授权信息读取
        if ($req->input('data_uuid')) {
            $data = Cache::get('login_data_' . $req->data_uuid);
        }
        else {
            $http = new HttpClient();
            $token  = $req->access_token;
            $openid = $req->openid;
            $data = $http->get('https://api.weixin.qq.com/sns/userinfo?access_token=' . $token  . '&openid=' . $openid);
            $data = @json_decode($data, true);
        }

        // \Log::error($data);

        if (!@$data['unionid']) {
            ThrowException::Conflict('授权信息失效~');
        }

        // 有手机号
        if ($phone) {
            SMS::verifyCode($phone, $phoneCode, 'login') || ThrowException::Conflict('验证码不正确');
            $data['phone'] = $phone;
        }

        DB::beginTransaction();

        $openidType = 'miniapp';
        
        list($user, $isCreated) = User::findOrCreateByApp($data, Auth::clientName(), $openidType);

        // 没有找到用户并且没有创建新用户
        if (!$user) {
            $dataUuid = uniqid();
            Cache::put('login_data_' . $dataUuid, $data, 300);

            return [
                'data_uuid' => $dataUuid,
                'is_need_phone' => 1
            ];
        } 

        // 绑定邀请人
        if ($req->input('inviter') && $isCreated) {
            $inviter = User::getEntity([
                'uuid' => $req->inviter
            ], false);

            $user->bindInviter($inviter, $req);
        }

        DB::commit();

        $token = Auth::generateToken($user);

        return [
            'token' => $token,
            'is_first_login' => $isCreated ? 1 : 0
        ];
    }


    // 抖音系小程序登陆
    public function loginWithByteDance(Request $req)
    {
        $rule = [
            // 'iv' => ['required'],
            // 'encrypt_data' => ['required'],
            // 'code' => ['required'],
        ];
        Validator::make($req->all(), $rule)->fails() && ThrowException::BadRequest();

        // 手机号简单验证
        if ($req->input('phone')) {
            if (strlen($req->phone) !== 11) {
                ThrowException::Conflict('手机号格式不正确~');
            }
        }

        // 如果有data_uuid，则直接从缓存中读取而不使用授权信息读取
        if ($req->input('data_uuid')) {
            $data = Cache::get('login_data_' . $req->data_uuid);
        }
        else {
            $data = ByteDance::get()->getUserInfo($req->code, $req->iv, $req->encrypt_data);
        }

        // 有手机号则验证手机号
        if ($req->input('phone')) {
            SMS::verifyCode($req->phone, $req->phone_code, 'login') || ThrowException::Conflict('验证码不正确');
            $data['phone'] = $req->phone;
        }

        DB::beginTransaction();

        $openidType = 'miniapp';

        list($user, $isCreated) = User::findOrCreateByByteDance($data, Auth::clientName(), $openidType);

        // 没有找到用户并且没有创建新用户
        if (!$user) {

            $dataUuid = uniqid();
            Cache::put('login_data_' . $dataUuid, $data, 300);

            return [
                'data_uuid' => $dataUuid,
                'is_need_phone_number' => 1
            ];
        } 

        // 绑定邀请人
        if ($req->input('inviter') && $isCreated) {
            $inviter = User::getEntity([
                'uuid' => $req->inviter
            ], false);

            $user->bindInviter($inviter, $req);
        }

        DB::commit();

        $token = Auth::generateToken($user);

        return [
            'token' => $token,
            'is_first_login' => $isCreated ? 1 : 0
        ];
    }


    // 淘宝/天猫小程序登陆
    public function loginWithTaobao(Request $req)
    {
        $rule = [
            'name' => ['required'],
            'headimg' => ['required'],
            'openid' => ['required']
        ];
        Validator::make($req->all(), $rule)->fails() && ThrowException::BadRequest();

        // \Log::error($req->all());

        $user = Auth::user();
        $isCreated =  false;

        if (!$user) {
            DB::beginTransaction();

            $openid  = $req->input('openid');
            $openidType = 'miniapp';

            $data = [
                'openid' => $openid,
                'name' => $req->input('name'),
                'headimg' => $req->input('headimg'),
            ];

            list($user, $isCreated) = User::findOrCreateByTaobao($data, Auth::clientName(), $openidType);


            if ($user && $isCreated) {
                // 绑定邀请人
                if ($req->input('inviter')) {
                    $inviter = User::getEntity([
                        'uuid' => $req->inviter
                    ], false);

                    $user->bindInviter($inviter, $req);
                }
            }

            DB::commit();
        }

        $token = Auth::generateToken($user);

        return [
            'token' => $token,
            'is_first_login' => $isCreated ? 1 : 0
        ];
    }
}
